﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;

namespace svnbacker
{
    public partial class Form1 : Form
    {
        NotifyIcon m_notificationIcon;
        ContextMenu m_trayMenu;
        
        public Form1()
        {
            InitializeComponent();

            m_trayMenu = new ContextMenu();
            m_trayMenu.MenuItems.Add("Backup!", OnBackup);
            m_trayMenu.MenuItems.Add("Settings", OnSettings);
            m_trayMenu.MenuItems.Add("Exit", OnExit);

            m_notificationIcon = new NotifyIcon();
            m_notificationIcon.Text = "svnbacker";


            Bitmap iconBitmap = Properties.Resources.icon;
            IntPtr hIcon = iconBitmap.GetHicon();
            Icon icon = Icon.FromHandle(hIcon);

            m_notificationIcon.Icon = new Icon(icon, 40, 40);
            m_notificationIcon.ContextMenu = m_trayMenu;
            m_notificationIcon.Visible = true;
            m_notificationIcon.DoubleClick += new EventHandler(m_notificationIcon_DoubleClick);

            Program.globalTimer = new Timer();
            Program.globalTimer.Interval = 60000;
            Program.globalTimer.Tick += new EventHandler(m_timer_Tick);
            Program.globalTimer.Start();

            Visible = false;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Visible = false;
            ShowInTaskbar = false;
            Hide();

            tbSVN.Text = Properties.Settings.Default.svntools;
            tbSourceRepo.Text = Properties.Settings.Default.source_repo;
            tbBackupDestination.Text = Properties.Settings.Default.backup_destination;

            nHour.Value = (Properties.Settings.Default.hour <= 12) ? Properties.Settings.Default.hour : Properties.Settings.Default.hour - 12;
            nMinute.Value = Properties.Settings.Default.minutes;
            cbbAmPm.SelectedIndex = (Properties.Settings.Default.hour <= 12) ? 0 : 1;
        }

        void m_timer_Tick(object sender, EventArgs e)
        {
            DateTime dtNow = DateTime.Now;

            if (dtNow.Hour == Properties.Settings.Default.hour && dtNow.Minute == Properties.Settings.Default.minutes)
            {
                OnBackup(this, null);
            }
        }

        void m_notificationIcon_DoubleClick(object sender, EventArgs e)
        {
            Visible = true;
        }

        private void OnSettings(object sender, EventArgs e)
        {
            Visible = true;
        }

        private void OnBackup(object sender, EventArgs e)
        {
            StringBuilder sb = new StringBuilder();

            string src = Properties.Settings.Default.source_repo;
            
            string header = string.Format("Starting Backup ({0})", src);
            sb.AppendLine(header);

            foreach (string dir in Directory.GetDirectories(src))
            {
                string path = string.Format(@"{0}\{1}", Properties.Settings.Default.backup_destination, Path.GetFileName(dir));
                string source = string.Format(@"{0}\{1}", Properties.Settings.Default.source_repo, Path.GetFileName(dir));
                string arguments = string.Format("hotcopy \"{0}\" \"{1}\"", source, path);

                Directory.CreateDirectory(path);

                string tools = Properties.Settings.Default.svntools;
                if ( tools == string.Empty )
                    tools = @".\svnadmin";
                else
                    tools = string.Format("\"{0}\\svnadmin\"", Properties.Settings.Default.svntools);

                // Debugging
                sb.AppendLine(string.Format("{0} {1}", tools, arguments));

                try
                {
                    ProcessStartInfo startInfo = new ProcessStartInfo();
                    startInfo.FileName = tools;
                    startInfo.Arguments = arguments;
                    startInfo.CreateNoWindow = true;
                    startInfo.UseShellExecute = false;
                    startInfo.WindowStyle = ProcessWindowStyle.Hidden;
                    Process p = Process.Start(startInfo);
                    p.WaitForExit();
                }
                catch (Exception ex)
                {
                    sb.AppendLine("Error");
                    sb.AppendLine(ex.Message);
                    sb.AppendLine(string.Format("{0} | {1} | {2}", path, source, arguments));
                    using (StreamWriter outfile = new StreamWriter(@".\error.txt"))
                    {
                        outfile.Write(sb.ToString());
                    }                    
                }
                
            }

            using (StreamWriter outfile = new StreamWriter( @".\debug.txt"))
            {
                outfile.Write(sb.ToString());
            }
        }

        private void OnExit(object sender, EventArgs e)
        {
            Program.globalTimer.Stop();
            Program.globalTimer.Dispose();

            m_notificationIcon.Dispose();

            Process.GetCurrentProcess().Kill();
            Application.Exit();
        }

        
        private void button1_Click(object sender, EventArgs e)
        {
            Properties.Settings.Default.hour = (cbbAmPm.SelectedText == "AM") ? (int)nHour.Value : (int)nHour.Value + 12;
            Properties.Settings.Default.minutes = (int)nMinute.Value;

            Properties.Settings.Default.svntools = tbSVN.Text;

            Properties.Settings.Default.source_repo = tbSourceRepo.Text;
            Properties.Settings.Default.backup_destination = tbBackupDestination.Text;
            Properties.Settings.Default.Save();
            button1.Enabled = false;
        }

        private void tbSourceRepo_TextChanged(object sender, EventArgs e)
        {
            button1.Enabled = true;
        }

        private void tbBackupDestination_TextChanged(object sender, EventArgs e)
        {
            button1.Enabled = true;
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            e.Cancel = true;
            Visible = false;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
            {
                tbSourceRepo.Text = folderBrowserDialog1.SelectedPath;
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
            {
                tbBackupDestination.Text = folderBrowserDialog1.SelectedPath;
            }
        }

        private void nHour_ValueChanged(object sender, EventArgs e)
        {
            button1.Enabled = true;
        }

        private void nMinute_ValueChanged(object sender, EventArgs e)
        {
            button1.Enabled = true;
        }

        private void cbbAmPm_SelectedValueChanged(object sender, EventArgs e)
        {
            button1.Enabled = true;
        }

        private void button4_Click(object sender, EventArgs e)
        {
            if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
            {
                tbSVN.Text = folderBrowserDialog1.SelectedPath;
            }
        }
    }
}
